# encoding: utf-8
from __future__ import unicode_literals

import binascii
import datetime

import snmpclient
from admin_highcharts.admin import HighchartsModelAdmin
from django.contrib import admin
from django.contrib import messages
from django.contrib.admin import FieldListFilter
from django.contrib.admin.utils import unquote
from django.contrib.auth.admin import UserAdmin, GroupAdmin
from django.core.exceptions import PermissionDenied
from django.db.models import Sum
from django.http import Http404, HttpResponseRedirect
from django.template.response import TemplateResponse
from django.utils.encoding import force_text
from django.utils.html import escape
from django.utils.text import capfirst
from django.utils.translation import ugettext_lazy as _
from easy_select2 import Select2 as Select2Widget
from import_export import fields
from import_export.admin import ExportActionModelAdmin
from import_export.resources import ModelResource

from core.filterspecs import MonthFilter
from core.forms import AdvancedSearchForm, PortInlineInlineForm
from core.modeladmin import ModelAdmin, TabularInline
from core.models import *
from core.utils import monthdays


@admin.register(Staff)
class StaffAdmin(UserAdmin):
    list_display = ('username', 'email', 'fullname', 'is_staff', 'grouplist')
    list_filter = ['is_staff', 'is_active', 'is_superuser']
    filter_horizontal = ['groups', 'user_permissions']
    search_fields = ['username', 'first_name', 'last_name']
    readonly_fields = ['last_login', 'date_joined']
    # form = StaffForm
    suit_list_filter_horizontal = ['is_staff', 'is_active', 'is_superuser']

    def have_add_permission(self, request):
        # return super(StaffAdmin, self).has_add_permission(request)
        return request.user.has_perm('auth.add_user')

    def have_change_permission(self, request, obj=None):
        # return super(StaffAdmin, self).has_change_permission(request, obj)
        return request.user.has_perm('auth.change_user')

    def have_delete_permission(self, request, obj=None):
        # return super(StaffAdmin, self).has_delete_permission(request, obj)
        return request.user.has_perm('auth.delete_user')

    def has_add_permission(self, request):
        return request.user.is_superuser or self.have_add_permission(request)

    def has_view_permission(self, request, obj=None):
        view_permission = 'view_%s' % self.opts.model_name
        # view_permission = 'view_%s' % self.model._meta.model_name
        return request.user.has_perm(self.opts.app_label + '.' + view_permission)

    def has_change_permission(self, request, obj=None):
        return request.user.is_superuser or (self.have_change_permission(request, obj) or
                                             self.has_view_permission(request, obj))

    def has_delete_permission(self, request, obj=None):
        return request.user.is_superuser or self.have_delete_permission(request, obj)

    def get_queryset(self, request):
        qs = super(StaffAdmin, self).get_queryset(request).order_by('-is_staff')
        if request.user.is_superuser:
            return qs
        if request.user.has_perm('auth.add_user'):
            return qs.filter(is_superuser=False)
        return qs.filter(id=request.user.id)

    def change_view(self, request, object_id, form_url='', extra_context=None):
        self.exclude = []
        extra_context = extra_context or {}
        if not request.user.is_superuser:
            defaults = {
                'read_only': True,
            }
            extra_context.update(defaults)
            if not self.have_add_permission(request):
                self.exclude = ['is_staff', 'is_active', 'is_superuser', 'groups', 'user_permissions']
        return super(StaffAdmin, self).change_view(request, object_id, form_url, extra_context=extra_context)

    def save_model(self, request, obj, form, change):
        if not request.user.is_superuser:
            obj.is_superuser = False
        obj.save()


@admin.register(Department)
class DepartmentAdmin(GroupAdmin):
    list_display = ('name', 'userlist',)
    filter_horizontal = ('permissions',)
    # form = DepartmentForm


@admin.register(AccessControl)
class AccessControlAdmin(ModelAdmin):
    list_display = ('name', 'content_type', 'codename')


class PortInline(TabularInline):
    model = Port
    extra = 0
    # exclude = ['state']
    readonly_fields = ['name', 'oid', 'state']
    form = PortInlineInlineForm
    fieldsets = ((None, {'fields': ('oid', 'name', 'description', 'direct', 'is_active', 'state', 'users')}),)
    suit_form_inlines_hide_original = True


@admin.register(Host)
class HostAdmin(ModelAdmin):
    list_display = ['description', 'hostname', 'snmp_community', 'snmp_port', 'is_active', 'state', 'operation']
    # list_display_links = ['description']
    list_filter = ['is_active']
    search_fields = ['description', 'hostname']
    inlines = [PortInline]
    readonly_fields = ['state']
    exclude = ['state']
    fieldsets = (
        (None, {
            'fields': (('description', 'hostname'), ('snmp_community', 'snmp_port'), 'is_active')
        }),
    )
    suit_list_filter_horizontal = ['is_active']

    def get_urls(self):
        from django.conf.urls import url
        from functools import update_wrapper

        def wrap(view):
            def wrapper(*args, **kwargs):
                return self.admin_site.admin_view(view)(*args, **kwargs)

            wrapper.model_admin = self
            return update_wrapper(wrapper, view)

        info = self.model._meta.app_label, self.model._meta.model_name

        urlpatterns = super(HostAdmin, self).get_urls()
        urlpatterns.insert(3, url(r'^(.+)/port/$', wrap(self.port_view), name='%s_%s_port' % info), )
        return urlpatterns
        # urls = super().get_urls()
        # my_urls = [
        #     path(r'^(.+)/port/$', self.admin_site.admin_view(self.port_view))
        # ]
        # return my_urls + urls

    def get_inline_instances(self, request, obj=None):
        inline_instances = []
        for inline_class in self.inlines:
            instance = inline_class(self.model, self.admin_site)
            if obj is not None:
                inline_instances.append(instance)
                self.exclude = []
            else:
                self.exclude = ['state']
        return inline_instances

    def port_view(self, request, object_id, form_url='', extra_context=None):
        if request.method == 'POST':
            if '_selected_action' in request.POST:
                host_id = request.POST.get('host_id')
                host = self.get_object(request, unquote(host_id))
                selects = request.POST.getlist('_selected_action')
                msg = _(u'%(name)s成功添加%(count)s端口.') % {'name': host.description, 'count': len(selects)}
                for select in selects:
                    ss = select.split('--')
                    port = Port()
                    port.host_id = host_id
                    port.oid = ss[0]
                    port.description = ss[1]
                    port.name = ss[2]
                    port.save()
                self.message_user(request, msg, messages.SUCCESS)
            return super(HostAdmin, self).changelist_view(request, extra_context)
        model = self.model
        obj = self.get_object(request, unquote(object_id))
        if obj is None:
            raise Http404(_(u'%(name)s不存在主键为%(key)s的对象.') % {
                'name': force_text(model._meta.verbose_name),
                'key': escape(object_id),
            })

        if not self.has_change_permission(request, obj):
            raise PermissionDenied
        opts = model._meta
        app_label = opts.app_label

        authorizations = snmpclient.cmdgen.CommunityData('snmpuser', obj.snmp_community, snmpclient.V2C)
        client = snmpclient.SnmpClient(obj.hostname, obj.snmp_port, [authorizations])
        data = []
        if client.alive:
            tables = client.matchtables('IF-MIB::ifIndex',
                                        ('IF-MIB::ifOperStatus', 'IF-MIB::ifAlias', 'IF-MIB::ifName', 'IF-MIB::ifType',
                                         'IF-MIB::ifHighSpeed', 'IF-MIB::ifPhysAddress'))
            # ips = client.gettable('IP-MIB::ipAdEntIfIndex')
            types = {'1': 'other', '6': 'ethernetCsmacd', '24': 'softwareLoopback', '53': 'propVirtual',
                     '117': 'gigabitEthernet', '131': 'tunnel', '136': 'l3ipvlan', '161': 'ieee8023adLag'}
            status = {'1': 'Up', '2': 'Down'}
            for k, v in tables.items():
                if len(v) >= 5:
                    if v[3] not in [6, 117]:
                        continue
                    # s = (str(v[5])).encode('hex').upper()
                    s = str(binascii.hexlify(v[5]._value).upper())
                    addr = ':'.join([s[i:i + 2] for i in range(2, len(s) - 2, 2)])
                    ty = '%s' % v[3]
                    if ty in types:
                        ty = types[ty]
                    if v[1] == '':
                        data.append([k, status['%s' % v[0]], v[2], v[2], ty, v[4], addr])
                    else:
                        data.append([k, status['%s' % v[0]], v[1], v[2], ty, v[4], addr])
                elif len(v) >= 4:
                    if v[2] not in [6, 117]:
                        continue
                    s = str(binascii.hexlify(v[3]._value).upper())
                    addr = ':'.join([s[i:i + 2] for i in range(2, len(s) - 2, 2)])
                    ty = '%s' % v[2]
                    if ty in types:
                        ty = types[ty]
                    if v[1] == '':
                        data.append([k, status['%s' % v[0]], v[2], v[2], ty, '', addr])
                    else:
                        data.append([k, status['%s' % v[0]], v[1], v[1], ty, '', addr])
                else:
                    # raise ValueError, v
                    self.message_user(request, '{0}'.format(k, v[1]))

        context = dict(self.admin_site.each_context(request),
                       title=_(u'添加端口: %s') % force_text(obj),
                       module_name=capfirst(force_text(opts.verbose_name_plural)),
                       result_headers=[_(u'索引'), _(u'状态'), _(u'描述'), _(u'名称'), _(u'类型'), _(u'速度'), _(u'硬件地址')],
                       results=data,
                       object=obj,
                       opts=opts,
                       preserved_filters=self.get_preserved_filters(request),
                       )
        context.update(extra_context or {})

        request.current_app = self.admin_site.name

        return TemplateResponse(request, ["admin/%s/%s/object_port.html" % (app_label, opts.model_name),
                                          "admin/%s/object_port.html" % app_label,
                                          "admin/object_port.html"
                                          ], context)

    def changelist_view(self, request, extra_context=None, **kwargs):
        if 'has_param' not in request.session and 'q' not in request.GET and 'all' not in request.GET and 'is_active__exact' not in request.GET:
            if 'HTTP_REFERER' in request.META:
                request.session['has_param'] = False
                return HttpResponseRedirect(reverse('admin:core_host_changelist') + "?is_active__exact=1")
        if 'has_param' in request.session:
            del request.session['has_param']
        view = super(HostAdmin, self).changelist_view(request, extra_context=extra_context)
        return view


class TrafficLogResource(ModelResource):
    in_bps = fields.Field()
    out_bps = fields.Field()

    class Meta:
        model = TrafficLog
#        fields = ['port', 'date', 'in_bits', 'out_bits', 'traffic_in', 'traffic_out', 'in_bps', 'out_bps']
        fields = ['port', 'date', 'in_bps', 'out_bps']
#        export_order = ['port', 'date', 'in_bits', 'out_bits', 'traffic_in', 'traffic_out', 'in_bps', 'out_bps']
        export_order = ['port', 'date','in_bps', 'out_bps']
        exclude = ['id']

    def dehydrate_port(self, obj):
        if isinstance(obj, dict):
            return u'合并端口'
        return u'%s by %s' % (obj.port.description, obj.port.host.description)

    def dehydrate_date(self, obj):
        if isinstance(obj, dict):
            return obj['date'].strftime('%Y-%m-%d %H:%M:%S')
        return obj.date.strftime('%Y-%m-%d %H:%M:%S')

#    def dehydrate_in_bits(self, obj):
#        if isinstance(obj, dict):
#            return obj['in_bits']
#        return obj.in_bits

#    def dehydrate_out_bits(self, obj):
#        if isinstance(obj, dict):
#            return obj['out_bits']
#        return obj.out_bits

#    def dehydrate_traffic_in(self, obj):
#        if isinstance(obj, dict):
#            return obj['traffic_in']
#        return obj.traffic_in

#    def dehydrate_traffic_out(self, obj):
##        if isinstance(obj, dict):
#            return obj['traffic_out']
#        return obj.traffic_out

    def dehydrate_in_bps(self, obj):
        if isinstance(obj, dict):
            return round(float(obj['in_bits']) / self.kmg, 3)
        # return '={0}/1024/1024/1024'.format(obj.in_bits)
        return round(float(obj.in_bits) / self.kmg, 3)

    def dehydrate_out_bps(self, obj):
        if isinstance(obj, dict):
            return round(float(obj['out_bits']) / self.kmg, 3)
        # return '={0}/1024/1024/1024'.format(obj.out_bits)
        return round(float(obj.out_bits) / self.kmg, 3)

    def get_export_headers(self):
#        return [u'端口', u'时间', u'流入(b/s)', u'流出(b/s)', u'流入(5分钟)', u'流出(5分钟)', u'流入(gb/s)', u'流出(gb/s)']
        return [u'端口', u'时间', u'流入(gb/s)', u'流出(gb/s)']

    def export(self, queryset=None, *args, **kwargs):
        one = kwargs.get('one', '0')
        kmg = int(kwargs.get('kmg', '1000'))
        self.kmg = kmg * kmg * kmg
        if one != '0' and queryset.values('port').distinct().count() > 1:
            queryset = queryset.values('date').annotate(in_bits=Sum('in_bits'), out_bits=Sum('out_bits'),
                                                        traffic_in=Sum('traffic_in'),
                                                        traffic_out=Sum('traffic_out')).order_by('-date')
        return super(TrafficLogResource, self).export(queryset, *args, **kwargs)

    # @classmethod
    # def field_from_django_field(self, field_name, django_field, readonly):
    #     """
    #     Returns a Resource Field instance for the given Django model field.
    #     """
    #     FieldWidget = self.widget_from_django_field(django_field)
    #     widget_kwargs = self.widget_kwargs_for_field(field_name)
    #     field = fields.Field(attribute=field_name, column_name=django_field.verbose_name,
    #             widget=FieldWidget(**widget_kwargs), readonly=readonly)
    #     return field


@admin.register(TrafficLog)
class TrafficLogAdmin(ModelAdmin, HighchartsModelAdmin, ExportActionModelAdmin):
    # class Media:
    #     js = ('suit3/js/datepicker/bootstrap-datepicker.js',)
    def calc(self, obj):
        if obj.in_bits is None:
            prev = obj.port.traffic_logs.filter(id__lt=obj.id).order_by('-date').first()
            if prev is not None:
                minus = obj.date - prev.date
                seconds = minus.seconds + minus.days * 86400
                in_bits = (obj.traffic_in - prev.traffic_in) / seconds * 8
                out_bits = (obj.traffic_out - prev.traffic_out) / seconds * 8
            else:
                in_bits = 0
                out_bits = 0
            obj.in_bits = in_bits
            obj.out_bits = out_bits
            obj.save()
        return 'ok'

    calc.short_description = u'流量计算'

    def in_bps(self, obj):
        return round(obj.in_bits / self.kmg, 3)

    in_bps.short_description = u'流入(gb/s)'

    def out_bps(self, obj):
        return round(obj.out_bits / self.kmg, 3)

    out_bps.short_description = u'流出(gb/s)'

    change_list_template = 'suit3/change_log.html'
    change_form_template = 'suit3/change_form.html'
#    list_display = ['port', 'name', 'date', 'in_bits', 'out_bits', 'traffic_in', 'traffic_out', 'in_bps', 'out_bps',
#                    'isvalid']
    list_display = ['port', 'name', 'date', 'in_bits', 'out_bits','in_bps', 'out_bps','isvalid']
    # list_filter = ['port__is_active', 'port__host', 'port', 'date']
    # list_per_page = 144
    # advanced_search_form = AdvancedSearchForm
    # other_search_fields = {}
    search_fields = ['port__description', 'port__name', 'port__host__description', 'port__host__hostname']
    formfield_overrides = {
        models.ForeignKey: {'widget': Select2Widget},
    }
    resource_class = TrafficLogResource
    # suit_list_filter_horizontal = ['port__is_active', 'port__host', 'port', 'date']

    # def lookup_allowed(self, lookup, value):
    #     if lookup in self.advanced_search_form.base_fields.keys():
    #         return True
    #     return super(TrafficLogAdmin, self).lookup_allowed(lookup, value)

    def get_export_data(self, file_format, queryset, *args, **kwargs):
        request = kwargs.get("request", None)
        if request is not None:
            kwargs.update({'one': request.session.get('one', '0'), 'kmg': request.session.get('kmg', '1000')})
        return super(TrafficLogAdmin, self).get_export_data(file_format, queryset, *args, **kwargs)

    def get_queryset(self, request):
        qs = super(TrafficLogAdmin, self).get_queryset(request)  # .exclude(in_bits=0, out_bits=0)
        if self.view_only:
            qs = qs.filter(port__users__in=self.user)
        started, expired = monthdays()
        started = request.GET.get('started', started)
        expired = request.GET.get('expired', expired)
        ports = request.GET.getlist('ports', self.ports)
        one = request.GET.get('one', '0')
        kmg = int(request.GET.get('kmg', '1000'))
        direct = request.GET.get('direct', '0')
        chart = request.GET.get('chart', '0')
        if started != '':
            if isinstance(started, str):  # or isinstance(started, unicode):
                started = datetime.datetime.strptime(started, '%Y-%m-%d')
            started = started.strftime('%Y-%m-%d 00:00:00')
            qs = qs.filter(date__gte=started)
        if expired != '':
            if isinstance(expired, str):  # or isinstance(expired, unicode):
                expired = datetime.datetime.strptime(expired, '%Y-%m-%d')
            nextday = expired + datetime.timedelta(days=1)
            nextday = nextday.strftime('%Y-%m-%d 00:00:00')
            qs = qs.filter(date__lt=nextday)
        if len(ports) > 0:
            qs = qs.filter(port_id__in=ports)
            if one == '1':
                qs.group_by = ['date']
        request.GET._mutable = True
        if 'started' in request.GET:
            request.GET.pop('started')
        if 'expired' in request.GET:
            request.GET.pop('expired')
        if 'ports' in request.GET:
            request.GET.pop('ports')
        if 'one' in request.GET:
            request.session['one'] = one
            request.GET.pop('one')
        if 'kmg' in request.GET:
            request.session['kmg'] = kmg
            request.GET.pop('kmg')
        if 'direct' in request.GET:
            request.GET.pop('direct')
        if 'chart' in request.GET:
            request.GET.pop('chart')
        request.GET._mutable = False
        # if one == '1':
        #     qs = qs.values('date').annotate(in_bits=Sum('in_bits'), out_bits=Sum('out_bits'))
        return qs

    def changelist_view(self, request, extra_context=None):
        extra_context = extra_context or {}
        started, expired = monthdays()
        self.view_only = not (request.user.is_superuser or request.user.has_perm('core.add_host'))
        if self.view_only:
            self.user = [request.user]
            self.ports = [Port.objects.filter(is_active=True, users__in=self.user).first().id, ]
        else:
            self.user = []
            self.ports = []
        started = request.GET.get('started', started)
        expired = request.GET.get('expired', expired)
        ports = request.GET.getlist('ports', self.ports)
        one = request.GET.get('one', '0')
        kmg = int(request.GET.get('kmg', '1000'))
        direct = request.GET.get('direct', '2')
        chart = request.GET.get('direct', '0')
        if isinstance(started, str):  # or isinstance(started, unicode):
            started = datetime.datetime.strptime(started, '%Y-%m-%d')
        if isinstance(expired, str):  # or isinstance(expired, unicode):
            expired = datetime.datetime.strptime(expired, '%Y-%m-%d')
        nextday = expired + datetime.timedelta(days=1)
        #     self.list_per_page = 288 * (nextday - started).days
        # else:
        #     self.list_per_page = 288
        self.kmg = kmg * kmg * kmg
        advance_form = AdvancedSearchForm(
            initial={'started': started, 'expired': expired, 'ports': ports, 'one': one, 'kmg': kmg, 'user': self.user})
        extra_context.update({'advance_form': advance_form})
        view = super(TrafficLogAdmin, self).changelist_view(request, extra_context)
        return view


@admin.register(TrafficChart)
class TrafficChartAdmin(ModelAdmin, HighchartsModelAdmin):
    def billing(self, obj):
        return self.billing

    billing.short_description = u'billing'

    change_list_template = 'suit3/change_chart.html'
    change_form_template = 'suit3/change_form.html'
    list_display = ['port', 'name', 'date', 'in_bits', 'out_bits', 'traffic_in', 'traffic_out']
    list_display = ['port', 'name', 'date', 'in_bits', 'out_bits', 'traffic_in', 'traffic_out']
    # list_filter = ['port__is_active', 'port__host', 'port', 'date']
    list_per_page = 144
    search_fields = ['port__description', 'port__name', 'port__host__description', 'port__host__hostname']
    formfield_overrides = {
        models.ForeignKey: {'widget': Select2Widget},
    }
    chart_type = 'spline'
    chart_category_name = 'date'
    chart_serial_names = ('in_bits', 'out_bits', 'billing')
    chart_key = 'port'

    def get_queryset(self, request):
        qs = super(TrafficChartAdmin, self).get_queryset(request)
        if self.view_only:
            qs = qs.filter(port__users__in=self.user)
        qs = qs.filter(isvalid=True)
        started, expired = monthdays()
        started = request.GET.get('started', started)
        expired = request.GET.get('expired', expired)
        ports = request.GET.getlist('ports', self.ports)
        one = request.GET.get('one', '0')
        kmg = int(request.GET.get('kmg', 1000))
        direct = request.GET.get('direct', '0')
        chart = request.GET.get('chart', '0')
        if started != '':
            if isinstance(started, str):  # or isinstance(started, unicode):
                started = datetime.datetime.strptime(started, '%Y-%m-%d')
            started = started.strftime('%Y-%m-%d 00:00:00')
            qs = qs.filter(date__gte=started)
        if expired != '':
            if isinstance(expired, str):  # or isinstance(expired, unicode):
                expired = datetime.datetime.strptime(expired, '%Y-%m-%d')
            nextday = expired + datetime.timedelta(days=1)
            nextday = nextday.strftime('%Y-%m-%d 00:00:00')
            qs = qs.filter(date__lt=nextday)
        if len(ports) > 0:
            qs = qs.filter(port_id__in=ports)
            if one == '1':
                qs.group_by = ['date']
        request.GET._mutable = True
        if 'started' in request.GET:
            request.GET.pop('started')
        if 'expired' in request.GET:
            request.GET.pop('expired')
        if 'ports' in request.GET:
            request.GET.pop('ports')
        if 'one' in request.GET:
            request.GET.pop('one')
        if 'kmg' in request.GET:
            request.GET.pop('kmg')
        if 'direct' in request.GET:
            request.GET.pop('direct')
        if 'chart' in request.GET:
            request.GET.pop('chart')
        request.GET._mutable = False
        return qs

    def changelist_view(self, request, extra_context=None):
        extra_context = extra_context or {}
        started, expired = monthdays()
        self.view_only = not (request.user.is_superuser or request.user.has_perm('core.add_host'))
        if self.view_only:
            self.user = [request.user]
            self.ports = [Port.objects.filter(is_active=True, users__in=self.user).first().id, ]
        else:
            self.user = []
            self.ports = [Port.objects.filter(is_active=True).first().id, ]
        started = request.GET.get('started', started)
        expired = request.GET.get('expired', expired)
        ports = request.GET.getlist('ports', self.ports)
        one = request.GET.get('one', '0')
        kmg = int(request.GET.get('kmg', '1000'))
        direct = request.GET.get('direct', '2')
        chart = request.GET.get('chart', '0')
        if isinstance(started, str):  # or isinstance(started, unicode):
            started = datetime.datetime.strptime(started, '%Y-%m-%d')
        if isinstance(expired, str):  # or isinstance(expired, unicode):
            expired = datetime.datetime.strptime(expired, '%Y-%m-%d')
        nextday = expired + datetime.timedelta(days=1)
        self.list_per_page = 288 * (nextday - started).days
        self.chart_one = one
        self.chart_direct = direct
        self.chart_kmg = kmg
        if one == '0' and len(ports) > 1:
            self.chart_serial_names = ('in_bits', 'out_bits')
        else:
            self.chart_serial_names = ('in_bits', 'out_bits', 'billing')
        if chart == '0':
            self.change_list_template = 'suit3/change_chart.html'
        else:
            self.change_list_template = 'suit3/change_echart.html'
        advance_form = AdvancedSearchForm(
            initial={'started': started, 'expired': expired, 'ports': ports, 'one': one, 'kmg': kmg, 'direct': direct,
                     'chart': chart, 'user': self.user})
        extra_context.update({'advance_form': advance_form})
        view = super(TrafficChartAdmin, self).changelist_view(request, extra_context)
        # if self.list_per_page == 8928:
        #     # point = round(cl.result_count * 0.05 + 1)
        #     point = 432
        #     qs = view.context_data['cl'].queryset.order_by('-in_bits')
        #     self.billing = qs[point].in_bits
        return view


@admin.register(Collection)
class CollectionAdmin(ModelAdmin):
    list_display = ['date', 'name', 'ip', 'is_active', 'message']


FieldListFilter.register(lambda f: isinstance(f, models.DateField), MonthFilter, True)

admin.site.unregister(User)
admin.site.unregister(Group)
admin.site.site_title = u'95流量计费系统1.01'
admin.site.site_header = u'95流量计费系统1.01'
Group._meta.verbose_name = u'部门'
Group._meta.verbose_name_plural = u'部门'
Group._meta.verbose_name_plural = u'部门'
